#pragma once

#include <sigc++/sigc++.h>
#include <deque>
#include <glibmm.h>

// tmp hack...
#include "../Shared/GObjHelpers.hpp"

namespace EGlib
{
  template <class T>  
  class MessageQueue : public BuildNG::Object
  {
  public:
    static Glib::RefPtr<MessageQueue<T> > create()
    {
      return Glib::RefPtr<MessageQueue<T> >(new MessageQueue<T>());
    }

    void post(const T &msg);
    T pop_blocking();

  private:
    std::deque<T>       queue;
    Glib::Mutex         lock;
    Glib::Cond          available_cond;
  };

  template <class T>
  void MessageQueue<T>::post(const T &msg)
  {
    lock.lock();
    try
    {
      queue.push_back(msg);
      int new_size = (int)queue.size();

      available_cond.signal();
      
      lock.unlock();
    }
    catch(...)
    {
      lock.unlock();
      throw;
    }
  }

  template <class T>
  T MessageQueue<T>::pop_blocking()
  {
    lock.lock();

    while(queue.size() == 0)
    {
      available_cond.wait(lock);
    }

    T ret = queue.front();
    queue.pop_front();
    if(queue.size() == 0)
    {
      available_cond.signal();
    }

    lock.unlock();

    return ret;
  }
}
